home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
INIT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-31
|
19KB
|
997 lines
/*
* .nn/init file handling
*/
#include "config.h"
#include "articles.h"
#include "term.h"
#include "keymap.h"
#include "menu.h"
export int in_init = 0; /* true when parsing init file */
export int alt_cmd_key; /* K_ when parse_command returns AC_KEYCMD */
static int init_err = 0; /* errors in init file */
/*VARARGS*/
init_message(va_alist)
va_dcl
{
char *fmt;
va_list ap;
va_start(ap);
if (in_init) {
fmt = va_arg1(char *);
printf("init error: ");
vprintf(fmt, va_args2toN);
putchar(NL);
init_err++;
} else
vmsg(va_args1toN);
va_end(ap);
}
visit_init_file(only_seq)
int only_seq;
{
extern FILE *loc_seq_hook, *glob_seq_hook;
in_init = 1;
load_init_file(relative(lib_directory, "init"), &glob_seq_hook, only_seq);
load_init_file("init", &loc_seq_hook, only_seq);
if (init_err) nn_exit(1);
in_init = 0;
}
#define START_SEQUENCE 555
static load_init_file(name, seq_hook_ptr, only_seq)
char *name;
FILE **seq_hook_ptr;
{
FILE *init;
char cmdbuf[512], *cmd, *term;
extern char *term_name;
/* use cmdbuf temporarily (to handle @ expansion) */
for (cmd = cmdbuf; *name; name++)
if (*name == '@') {
term = term_name;
while (term && *term) *cmd++ = *term++;
} else
*cmd++ = *name;
*cmd = NUL;
name = cmdbuf;
if (*name != '/')
name = relative(nn_directory, name);
init = open_file(name, OPEN_READ);
if (init == NULL) return;
while (fgets(cmdbuf, 512, init)) {
if (only_seq) {
if (!is_sequence(cmdbuf)) continue;
*seq_hook_ptr = init;
return;
}
/* we use AC_REDRAW to avoid !-commands clear the screen */
if (parse_command(cmdbuf, AC_REDRAW, init) == START_SEQUENCE) {
if (seq_hook_ptr) {
*seq_hook_ptr = init;
return; /* no close !! */
} else {
init_message("load file contains 'sequence'");
fclose(init);
return;
}
}
}
fclose(init);
}
#define MAXARG 10
static char *argvec[MAXARG + 2];
static int argc;
static char *strip_str(cmd)
register char *cmd;
{
if (cmd == NULL) return cmd;
while (*cmd && isspace(*cmd)) cmd++;
if (*cmd == NUL || *cmd == NL) return NULL;
return cmd;
}
static split_command(cmd)
register char *cmd;
{
/* split command string */
for (argc = 0; argc < MAXARG + 2; argc++) argvec[argc] = NULL;
strip_more:
if ((cmd = strip_str(cmd)) == NULL || *cmd == '#') return 0;
if (*cmd == ':') {
cmd++;
goto strip_more;
}
argc = 0;
argvec[0] = cmd;
if (in_init)
while (*cmd) {
if (*cmd == NL) {
*cmd = NUL;
break;
}
cmd++;
}
return 1;
}
static char *argv(i)
int i;
{
register char *cmd;
if (i > MAXARG) return NULL;
if (argc <= i)
if (cmd = argvec[argc])
while (argc <= i) {
while (*cmd && !isspace(*cmd)) cmd++;
if (*cmd == NUL) {
argc = MAXARG;
break;
}
*cmd++ = NUL;
if ((cmd = strip_str(cmd)) == NULL) {
argc = MAXARG;
break;
}
argvec[++argc] = cmd;
}
else
argc = MAXARG;
return argvec[i];
}
static is_sequence(cmd)
char *cmd;
{
if (!split_command(cmd)) return 0;
if ((cmd = argv(0)) == NULL) return 0;
return strcmp(cmd, "sequence") == 0;
}
/*
* parse a command (also :-commands)
*/
static char *sw_string;
#define SWITCH(str) \
for (sw_string = str; sw_string; sw_string = NULL)
#define CASE(str) \
if (strcmp(sw_string, str) == 0)
#define ARG(i, str) (argv(i) && strcmp(argv(i), str) == 0)
#define ARGVAL(i) atol(argv(i))
#define ARGTAIL argvec[argc]
struct alt_commands {
char *alt_name;
int alt_len;
int alt_type;
} alt_commands[] = {
"admin", 5, 0,
"cd", 2, 1,
"compile", 7, 0,
"coredump", 8, 0,
"decode", 6, 0,
"define", 6, 0,
"help", 4, 2,
"local", 5, 3,
"man", 3, 0,
"map", 3, -1,
"map both", 8, 4,
"map key", 7, 0,
"map menu", 8, 4,
"map show", 8, 4,
"mkdir", 5, 1,
"patch", 5, 0, /* QUICK HACK */
"print", 5, 0, /* QUICK HACK */
"pwd", 3, 0,
"rmail", 5, 0,
"set", 3, 3,
"show", 4, -1,
"show groups", 11, -1,
"show groups all", 15, 0,
"show groups subscr", 18, 0,
"show groups total", 17, 0,
"show groups unsub", 17, 0,
"show kill", 9, 0,
"show map", 8, -1,
"show map #", 10, 0,
"show map key", 12, 0,
"show map menu", 13, 0,
"show map show", 13, 0,
"sort", 4, -1,
"sort age", 8, 0,
"sort arrival", 12, 0,
"sort subject", 12, 0,
"toggle", 6, 3,
"unread", 6, 0,
"unset", 5, 3,
"unshar", 6, 0, /* QUICK HACK */
NULL, 0, 0
};
alt_completion(buf, index)
char *buf;
int index;
{
static char *head, *tail = NULL, buffer[FILENAME];
static int len;
static struct alt_commands *alt, *help_alt;
static int (*other_compl)();
int temp;
register char *p, *q;
extern int file_completion(), var_completion(), cmd_completion();
extern int list_offset;
if (other_compl) {
temp = (*other_compl)(buf, index);
if (index == 0 && temp == 1 && tail) strcpy(tail, head);
if (index < 0 || (index == 0 && temp == 0)) {
other_compl = NULL;
list_offset = 0;
}
return temp;
}
if (index < 0) return 0;
if (buf) {
head = buf;
tail = buf + index;
alt = help_alt = alt_commands;
len = tail - head;
other_compl = NULL;
for (; alt->alt_name; alt++) {
if (len <= alt->alt_len || head[alt->alt_len] != SP) continue;
index = strncmp(alt->alt_name, head, alt->alt_len);
if (index < 0) continue;
if (index > 0) break;
if (alt->alt_type < 0) {
if (len > alt->alt_len) continue;
break;
}
if (alt->alt_type == 0) return -1; /* cannot be further compl */
head += alt->alt_len;
while (*head && *head == SP) head++;
len = tail - head;
temp = -1;
switch (alt->alt_type) {
case 1:
other_compl = file_completion;
tail = NULL;
temp = file_completion(head, len);
break;
case 2:
other_compl = file_completion;
sprintf(buffer, "%s.%s",
relative(lib_directory, "help"), head);
len = strlen(buffer);
head = buffer + len;
list_offset = 5;
temp = file_completion(buffer, len);
break;
case 3:
/* [set ]variable[ value] */
for (p = head; *p; )
if (*p++ == SP) return -1;
other_compl = var_completion;
tail = NULL;
temp = var_completion(head, len);
break;
case 4:
/* [map XXX ]Y command[ N] */
for (p = head, temp = 0; *p; )
if (*p++ == SP) {
while (*p && *p == SP) p++;
head = p;
temp++;
}
if (temp != 1) return -1;
other_compl = cmd_completion;
tail = NULL;
len = p - head;
temp = cmd_completion(head, len);
break;
}
if (temp <= 0) other_compl = NULL;
return temp;
}
alt = alt_commands;
return 1;
}
if (index) {
list_completion((char *)NULL);
if (help_alt->alt_name == NULL) help_alt = alt_commands;
list_offset = 0;
if (p = strrchr(head, ' ')) list_offset = p - head;
while (help_alt->alt_name) {
if (len > help_alt->alt_len ||
(index = strncmp(help_alt->alt_name, head, len)) < 0) {
help_alt++;
continue;
}
if (index > 0) {
help_alt = alt_commands;
break;
}
p = help_alt->alt_name;
if (list_completion(p) == 0) break;
temp = help_alt->alt_len;
do help_alt++;
while ((q = help_alt->alt_name) && help_alt->alt_len > temp &&
strncmp(p, q, temp) == 0);
}
fl;
list_offset = 0;
return 1;
}
for (; alt->alt_name; alt++) {
if (len == 0)
index = 0;
else
index = strncmp(alt->alt_name, head, len);
if (index < 0) continue;
if (index > 0) break;
p = alt->alt_name;
sprintf(tail, "%s ", p + len);
temp = alt->alt_len;
do alt++;
while ((q = alt->alt_name) && alt->alt_len > temp &&
strncmp(p, q, temp) == 0);
return 1;
}
return 0;
}
parse_command(cmd, ok_val, initf)
char *cmd;
int ok_val;
FILE *initf;
{
extern char *m_define(), *parse_enter_macro();
int i;
if (!split_command(cmd)) return ok_val;
if (*ARGTAIL == '!') {
if (run_shell(ARGTAIL+1,
ok_val == AC_PROMPT ? 1 :
ok_val == AC_UNCHANGED ? -1 : 0) && ok_val != AC_UNCHANGED) {
any_key(0);
return AC_REDRAW;
}
return ok_val;
}
SWITCH( argv(0) ) {
CASE( "unset" ) {
if (argv(1) == NULL) goto stx_err;
if (set_variable(argv(1), 0, (char *)NULL))
return AC_REDRAW;
else
return ok_val;
}
CASE( "local" ) {
if (ARGTAIL == NULL) goto stx_err;
cmd = argv(1);
if (!push_variable(cmd)) return ok_val;
if (ARGTAIL && set_variable(cmd, 1, ARGTAIL))
return AC_REDRAW;
else
return ok_val;
}
CASE( "set" ) {
if (ARGTAIL == NULL) {
disp_variables();
return AC_REDRAW;
}
cmd = argv(1); /* get ARGTAIL right */
if (set_variable(cmd, 1, ARGTAIL))
return AC_REDRAW;
else
return ok_val;
}
CASE( "toggle" ) {
if (argv(1) == NULL) goto stx_err;
toggle_variable(argv(1));
break;
}
CASE( "define" ) {
if (in_init) {
if (argv(1) == NULL) {
init_message("macro number missing");
break;
}
m_define(argv(1), initf);
} else
if (m_define(argv(1), (FILE *)NULL))
return AC_REDRAW;
break;
}
CASE( "map" ) {
if (argv(2) == NULL) {
if (do_show("map", 1))
return AC_REDRAW;
break;
}
do_map();
break;
}
CASE( "cd" ) {
if (change_dir(argv(1), in_init))
init_message("chdir %s FAILED", argv(1));
break;
}
if (in_init) {
CASE( "load" ) {
if (argv(1)) load_init_file(argv(1), (FILE **)NULL, 0);
break;
}
CASE( "on" ) {
parse_on_to_end(initf);
break;
}
CASE( "end" ) {
break;
}
CASE( "sequence" ) {
return START_SEQUENCE;
}
print_command("unknown command");
break;
}
/*
* commands only available from : command line
*/
if (ok_val != AC_REDRAW) {
extern in_menu_mode;
alt_cmd_key = lookup_command(sw_string,
in_menu_mode ? K_ONLY_MENU : K_ONLY_MORE);
if (alt_cmd_key != K_INVALID && alt_cmd_key != K_HELP)
return AC_KEYCMD;
}
CASE( "q" ) {
break;
}
CASE( "Q" ) {
return AC_QUIT;
}
CASE( "q!" ) {
if (restore_bak())
return AC_QUIT;
break;
}
CASE( "x" ) {
update_rc(current_group);
return AC_QUIT;
}
CASE( "help" ) {
if (argv(1) == NULL)
display_help("help");
else
display_help(argv(1));
return AC_REDRAW;
}
CASE( "man" ) {
char *manual;
group_header *orig_group;
int orig_layout, orig_fsort;
import int fmt_linenum, dont_sort_folders;
manual = relative(lib_directory, "Manual");
if (!file_exist(manual, "fr")) {
manual = relative(db_directory, "Manual");
if (!file_exist(manual, "fr")) {
msg("Online manual is not available");
break;
}
}
orig_group = current_group;
orig_layout = fmt_linenum;
orig_fsort = dont_sort_folders;
fmt_linenum = 4;
dont_sort_folders = 1;
folder_menu(manual);
fmt_linenum = orig_layout;
dont_sort_folders = orig_fsort;
init_group(orig_group);
return AC_REDRAW;
}
CASE( "sort" ) {
if ARG(1, "age")
unsort_articles(0);
else if (ARG(1, "no") || ARG(1, "arrival"))
unsort_articles(1);
else
sort_articles();
return AC_REORDER;
}
CASE( "unread" ) {
group_header *gh;
int ix = 1;
if (argv(1) && (gh = lookup(argv(1))) != NULL)
ix = 2;
else
gh = current_group;
if (restore_rc(gh, argv(ix) ? ARGVAL(ix) : 0))
if (gh == current_group) return AC_HEADER;
break;
}
CASE( "dump" ) {
if (do_show(argv(1), 2))
return AC_REDRAW;
break;
}
CASE( "show" ) {
if (do_show(argv(1), 2))
return AC_REDRAW;
break;
}
CASE( "compile" ) {
import int do_kill_handling;
clrdisp();
rm_kill_file();
free_kill_entries();
do_kill_handling = init_kill() && do_kill_handling;
return AC_REDRAW;
}
CASE( "pwd" ) {
FILE *p = popen("exec pwd", "r");
char dir[FILENAME];
if (p) {
if (fgets(dir, FILENAME, p)) {
dir[strlen(dir) - 1] = NUL;
msg("%s", dir);
}
pclose(p);
}
break;
}
CASE( "rmail" ) {
import char *mail_box;
group_header *orig_group;
if (mail_box == NULL) {
msg("'mail' path not defined");
break;
}
orig_group = current_group;
folder_menu(mail_box);
init_group(orig_group);
return AC_REDRAW;
}
CASE( "mkdir" ) {
char *dir, *run_mkdir();
char name_buf[FILENAME];
if (dir = run_mkdir(argv(1), name_buf)) {
prompt("Change to %s", dir);
if (yes(0)) change_dir(dir, 0);
}
break;
}
CASE( "sh" ) {
suspend_nn();
s_redraw = 0;
return AC_REDRAW;
}
CASE( "admin" ) {
group_header *cur_group;
cur_group = current_group;
no_raw();
clrdisp();
printf("\n\n\n\rADMINISTRATION MODE\r\n\n\n");
admin_mode((char *)NULL);
clrdisp();
raw();
init_group(cur_group);
return AC_REDRAW;
}
CASE( "coredump" ) {
unset_raw();
abort();
}
msg("unknown command: \"%s\"", argv(0));
}
return ok_val;
stx_err:
print_command("syntax error");
return ok_val;
}
static print_command(str)
char *str;
{
char **av;
if (!in_init) {
msg(str);
return;
}
printf("\r%s:", str);
for (av = argvec; *av; av++)
printf(" %s", *av);
putchar(NL);
}
static do_show(table, mode_arg)
char *table;
int mode_arg;
{
if (in_init || table == NULL) return 0;
no_raw();
SWITCH( table ) {
CASE( "kill" ) {
clrdisp();
dump_kill_list();
break;
}
CASE( "groups" ) {
clrdisp();
if ARG(mode_arg, "all")
group_overview(1);
else
if ARG(mode_arg, "total")
group_overview(2);
else
if ARG(mode_arg, "unsub")
group_overview(3);
else
group_overview(0);
break;
}
CASE( "map" ) {
if (argv(mode_arg) == NULL) {
init_message("map name missing");
goto err;
}
if (argv(mode_arg)[0] == '#') {
clrdisp();
dump_multi_keys();
break;
}
SWITCH( argv(mode_arg) ) {
CASE( "key" ) {
clrdisp();
dump_global_map();
break;
}
CASE( "menu" ) {
clrdisp();
dump_key_map(menu_key_map, "menu", K_ONLY_MENU);
break;
}
CASE( "show" ) {
clrdisp();
dump_key_map(more_key_map, "show", K_ONLY_MORE);
break;
}
init_message("unknown map '%s'", argv(mode_arg));
goto err;
/*NOTREACHED*/
}
break;
}
init_message("unknown table '%s'", table);
goto err;
/*NOTREACHED*/
}
raw();
return 1;
err:
raw();
return 0;
}
static do_map()
{
int code, map_menu, map_show;
SWITCH( argv(1) ) {
CASE( "key" ) {
if (argv(3) == NULL) break;
global_key_map[parse_key(argv(2))] = parse_key(argv(3));
return;
}
if (argv(1)[0] == '#') {
char multi_buffer[16], *mb;
int i, parse_key();
if (!isdigit(argv(1)[1])) break;
for (i = 2, mb = multi_buffer; argv(i); i++)
*mb++ = (char)parse_key(argv(i));
*mb = NUL;
enter_multi_key(K_function(argv(1)[1] - '0'),
copy_str(multi_buffer));
return;
}
code = K_UNBOUND;
map_menu = map_show = 0;
CASE( "menu" ) {
map_menu++;
}
CASE( "show" ) {
map_show++;
}
CASE( "both" ) {
map_menu++;
map_show++;
}
if (map_menu) {
if (argv(3))
code = lookup_command(argv(3), K_ONLY_MENU);
if (code == K_EQUAL_KEY) {
if (argv(4))
code = menu_key_map[parse_key(argv(4))];
else
goto mac_err;
} else
if (code == K_MACRO || code == K_ARTICLE_ID)
if (argv(4))
code |= atoi(argv(4));
else
goto mac_err;
if (code != K_INVALID) {
menu_key_map[parse_key(argv(2))] = code;
if (!map_show) return;
}
}
if (map_show) {
if (argv(3))
code = lookup_command(argv(3), K_ONLY_MORE);
if (code == K_EQUAL_KEY) {
if (argv(4))
code = menu_key_map[parse_key(argv(4))];
else
goto mac_err;
} else
if (code == K_MACRO)
if (argv(4))
code |= atoi(argv(4));
else
goto mac_err;
if (code != K_INVALID) {
more_key_map[parse_key(argv(2))] = code;
return;
}
}
if (argv(4)) break;
if (code == K_INVALID) {
init_message("unknown key command: %s", argv(3));
return;
}
}
print_command("syntax error");
return;
mac_err:
print_command("last argument missing");
return;
}
static parse_on_to_end(f)
FILE *f;
{
register char *cp;
char buf[256];
if (argv(1) == NULL) goto on_err;
SWITCH ( argv(1) ) {
CASE( "entry" ) {
import char *dflt_enter_macro;
group_header *gh, *get_group_search();
char *macro;
int i;
macro = parse_enter_macro(f, NL);
if (ARGTAIL) {
for (i = 2; argv(i); i++) {
start_group_search(argv(i));
while (gh = get_group_search())
gh->enter_macro = macro;
}
} else
dflt_enter_macro = macro;
break;
}
/* CASE( "exit" ) {
import char *dflt_exit_macro;
dflt_exit_macro = parse_enter_macro(f, NL);
break;
}
*/
CASE( "slow" ) {
import int terminal_speed, slow_speed;
if (terminal_speed > (slow_speed / 10)) goto skip_to_end;
break;
}
CASE( "fast" ) {
import int terminal_speed, slow_speed;
if (terminal_speed <= (slow_speed / 10)) goto skip_to_end;
break;
}
CASE( "term" ) {
extern char *term_name;
if (argv(2) == NULL || strcmp(argv(2), term_name)) goto skip_to_end;
break;
}
goto on_err;
}
return 0;
skip_to_end:
while (fgets(buf, 256, f) != NULL) {
for (cp = buf; *cp && isascii(*cp) && isspace(*cp); cp++);
if (strncmp(cp, "end", 3) == 0) return 0;
}
init_message("end missing (on %s)", argv(1));
on_err:
init_message("on `what'?");
}
display_help(subject)
char *subject;
{
char file[FILENAME];
strcpy(file, "help.");
strcpy(file+5, subject);
display_file(file, CLEAR_DISPLAY | CONFIRMATION);
}